//
//  NSObject+Coding.m
//  QuickCure
//
//  Created by 胡不归是大虾 on 16/9/22.
//  Copyright © 2016年 haoge. All rights reserved.
//

#import "NSObject+Coding.h"
#import <objc/runtime.h>
@implementation NSObject (Coding)
#pragma mark--方法实现
-(void)encode:(NSCoder*)aCoder
{
    //获得当前类
    Class cls = [self class];
    //创建一个循环,只有在当前类是NSObject这个根类的时候才跳出循环
    //这样可以实现从子类逐层归档和解档父类的属性
    while (cls && cls != [NSObject class]) {
        //取出当前类的所有属性
        unsigned int outCount = 0;
//        class_copyPropertyList(<#__unsafe_unretained Class cls#>, <#unsigned int *outCount#>)
        Ivar* ivars = class_copyIvarList(cls, &outCount);
        //遍历实例变量
        for (int i = 0; i < outCount; i++) {
            Ivar ivar = ivars[i];
            //取出变量名,键
            NSString* key = [NSString stringWithUTF8String:ivar_getName(ivar)];
            //判断该变量名是否是需要忽略的,先判断忽略列表是否实现
            if ([self respondsToSelector:@selector(ignoredNames)]) {
                if ([[self ignoredNames] containsObject:key]) {
                    continue;
                }
            }
            //取出变量的值
            id value = [self valueForKey:key];
            //归档
            [aCoder encodeObject:value forKey:key];
        }
        free(ivars);
        //在最后将cls赋值为父类的class
        cls = [cls superclass];
    }
}
-(void)decode:(NSCoder*)aDecoder
{
    Class cls = [self class];
    while (cls && cls != [NSObject class]) {
        //取到所有类中所有实例变量
        unsigned int outCount = 0;
        Ivar* ivars = class_copyIvarList(cls, &outCount);
        //遍历
        for (int i = 0; i< outCount; i++) {
            Ivar ivar = ivars[i];
            //取出变量名
            NSString* key = [NSString stringWithUTF8String:ivar_getName(ivar)];
            //忽略列表判断
            if ([self respondsToSelector:@selector(ignoredNames)]) {
                if ([[self ignoredNames] containsObject:key]) {
                    continue;
                }
            }
            //取出值
            id value = [aDecoder decodeObjectForKey:key];
            //赋值
            [self setValue:value forKey:key];
        }
        free(ivars);
        cls = [cls superclass];
    }
}
@end
